#pragma once
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include "GridStructs.h"

class FileIO {
public:
    // 读取网格文件
    static void readGridFile(const std::string& filename, 
                           GridSize& size,
                           std::vector<std::vector<double>>& coord,
                           std::vector<double>& zcorn) {
        std::ifstream file(filename);
        if (!file) {
            throw std::runtime_error("无法打开网格文件: " + filename);
        }

        std::string line;
        bool reading_data = false;
        std::string keyword;

        while (std::getline(file, line)) {
            if (line.empty() || line[0] == '#') continue;

            if (line == "/") {
                reading_data = false;
                keyword.clear();
                continue;
            }

            if (line == "SPECGRID") {
                keyword = "SPECGRID";
                reading_data = true;
                continue;
            }
            else if (line == "COORD") {
                keyword = "COORD";
                reading_data = true;
                continue;
            }
            else if (line == "ZCORN") {
                keyword = "ZCORN";
                reading_data = true;
                continue;
            }

            if (!reading_data) continue;

            std::istringstream iss(line);
            if (keyword == "SPECGRID") {
                iss >> size.Nx >> size.Ny >> size.Nz;
            }
            else if (keyword == "COORD") {
                std::vector<double> point(6);
                for (int i = 0; i < 6; ++i) {
                    iss >> point[i];
                }
                coord.push_back(point);
            }
            else if (keyword == "ZCORN") {
                double value;
                while (iss >> value) {
                    zcorn.push_back(value);
                }
            }
        }
    }

    // 读取属性文件
    static void readPropertiesFile(const std::string& filename,
                                 GridProperties& props) {
        std::ifstream file(filename);
        if (!file) {
            throw std::runtime_error("无法打开属性文件: " + filename);
        }

        std::string line;
        bool reading_data = false;
        std::string keyword;

        while (std::getline(file, line)) {
            if (line.empty() || line[0] == '#') continue;

            if (line == "/") {
                reading_data = false;
                keyword.clear();
                continue;
            }

            if (line == "YOUNGMOD") {
                keyword = "YOUNGMOD";
                reading_data = true;
                continue;
            }
            else if (line == "POISSONR") {
                keyword = "POISSONR";
                reading_data = true;
                continue;
            }
            else if (line == "ROCKDEN") {
                keyword = "ROCKDEN";
                reading_data = true;
                continue;
            }
            else if (line == "PORO") {
                keyword = "PORO";
                reading_data = true;
                continue;
            }

            if (reading_data) {
                processPropertyLine(line, keyword, props);
            }
        }
    }

private:
    // 处理属性行
    static void processPropertyLine(const std::string& line,
                                  const std::string& keyword,
                                  GridProperties& props) {
        std::istringstream iss(line);
        std::string value_str;
        while (iss >> value_str) {
            if (value_str.find('*') != std::string::npos) {
                size_t pos = value_str.find('*');
                int count = std::stoi(value_str.substr(0, pos));
                double value = std::stod(value_str.substr(pos + 1));

                if (keyword == "YOUNGMOD")
                    props.youngmod.insert(props.youngmod.end(), count, value);
                else if (keyword == "POISSONR")
                    props.poissonr.insert(props.poissonr.end(), count, value);
                else if (keyword == "ROCKDEN")
                    props.rockden.insert(props.rockden.end(), count, value);
                else if (keyword == "PORO")
                    props.poro.insert(props.poro.end(), count, value);
            }
            else {
                double value = std::stod(value_str);
                if (keyword == "YOUNGMOD")
                    props.youngmod.push_back(value);
                else if (keyword == "POISSONR")
                    props.poissonr.push_back(value);
                else if (keyword == "ROCKDEN")
                    props.rockden.push_back(value);
                else if (keyword == "PORO")
                    props.poro.push_back(value);
            }
        }
    }
};